﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data.Entity.Migrations;

using Seven.Core.IInitialize;
using Seven.EntityBasic;
using Seven.Entity;
using Seven.MsSql.Context;

namespace Seven.MsSql.Initialize
{
    /// <summary>
    /// 数据库初始化策略
    /// </summary>
    internal sealed class CreateConfiguration : CreateDatabaseIfNotExists<EFDbContext>
    {

    }

    /// <summary>
    /// 数据库迁移策略
    /// </summary>
    internal sealed class MigrateConfiguration : DbMigrationsConfiguration<EFDbContext>
    {
        public MigrateConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

        HrOrganization Company;
        HrOrganization Dept;
        HrStaff Staff;
        SysUser User;

        protected override void Seed(EFDbContext context)
        {
            //OrganInit(context);
            //StaffInit(context);
            //UserInit(context);

            //MenuInit(context);
            //MenuFunctionInit(context);
            //UserBaseConfigInit(context);
        }

        public void MenuInit(EFDbContext context)
        {
            DbSet<SysMenu> MenuSet = context.Set<SysMenu>();
            SysMenu SystemSetMenu = new SysMenu { Name = "系统设置", Code = "99", SortNumber = 99, IconCls = "", IsShow = true, IsSystem = true, CreateUserName = "admin", CreateDate = DateTime.Now };
            MenuSet.AddOrUpdate(a => a.Name, SystemSetMenu);
            context.SaveChanges();

            List<SysMenu> Menus = new List<SysMenu> 
            { 
                new SysMenu { Name = "菜单管理", Code = "9999", SortNumber = 99, IconCls = "", ParentID = SystemSetMenu.ID, ControllerName = "Menu", ActionName = "ManageIndex", IsShow = true, IsSystem = true, CreateUserName = "admin", CreateDate = DateTime.Now }
            };

            Menus.ForEach(m => MenuSet.AddOrUpdate(a => a.Name, m));
            context.SaveChanges();
        }

        public void MenuFunctionInit(EFDbContext context)
        {
            var Menus = context.Set<SysMenu>().Where(w => (w.ControllerName != "" && w.ControllerName != null) && (w.ActionName != "" && w.ActionName != null)).Select(s => new { s.ID, s.ActionName });
            var MenuFunctions = new List<SysMenuFunction>();
            var MenuPermissions = new List<SysMenuPermission>();
            foreach (var m in Menus.ToList())
            {
                MenuFunctions.Add(new SysMenuFunction { Name = "首页", Type = FunctionType.页面, SortNumber = 1, MenuID = m.ID, ActionName = m.ActionName, IsShow = true, CreateUserName = "admin", CreateDate = DateTime.Now });
                MenuPermissions.Add(new SysMenuPermission { Name = "访问", Type = PermissionType.访问, MenuID = m.ID, SortNumber = 1, IsShow = true, CreateUserName = "admin", CreateDate = DateTime.Now });
            }
            context.Set<SysMenuFunction>().AddOrUpdate(a => new { a.ActionName, a.MenuID }, MenuFunctions.ToArray());
            context.Set<SysMenuPermission>().AddOrUpdate(a => new { a.Name, a.MenuID }, MenuPermissions.ToArray());
            context.SaveChanges();
        }

        public void OrganInit(EFDbContext context)
        {
            //独立创建公司，需要拿到ID
            DbSet<HrOrganization> OrganSet = context.Set<HrOrganization>();
            Company = new HrOrganization { Name = "测试公司-七色花", ShortName = "七色花", Type = OrganType.公司, CreateUserName = "admin", CreateDate = DateTime.Now };
            OrganSet.AddOrUpdate(a => a.Name, Company);
            context.SaveChanges();

            //创建部门
            Dept = new HrOrganization { Name = "测试部门-开发部", ShortName = "开发部", Type = OrganType.部门, ParentID = Company.ID, SortNumber = 10, CreateUserName = "admin", CreateDate = DateTime.Now };
            List<HrOrganization> Depts = new List<HrOrganization>
            {
                new HrOrganization { Name="测试部门-测试部",ShortName="测试部", Type = OrganType.部门,ParentID = Company.ID,SortNumber=20, CreateUserName = "admin",CreateDate=DateTime.Now }
            };
            Depts.Add(Dept);

            Depts.ForEach(m => OrganSet.AddOrUpdate(a => a.Name, m));
            context.SaveChanges();
        }

        public void StaffInit(EFDbContext context)
        {
            Staff = new HrStaff { RealName = "老王", Sex = Sex.男, CompanyID = Company.ID, DeptID = Dept.ID, CreateUserName = "admin", CreateDate = DateTime.Now };
            List<HrStaff> Staffs = new List<HrStaff>();
            Staffs.Add(Staff);
            DbSet<HrStaff> StaffSet = context.Set<HrStaff>();
            Staffs.ForEach(m => StaffSet.AddOrUpdate(a => a.RealName, m));
            context.SaveChanges();
        }

        public void UserInit(EFDbContext context)
        {
            User = new SysUser { UserName = "admin", PassWord = "aUe8fkpIPzQ=", LoginCode = null, StaffID = Staff.ID, CreateUserName = "admin", CreateDate = DateTime.Now };
            List<SysUser> Users = new List<SysUser>();
            Users.Add(User);
            Users.Add(new SysUser { UserName = "lixilin", PassWord = "aUe8fkpIPzQ=", LoginCode = "cat", Staff = new HrStaff { RealName = "钢管", Sex = Sex.保密, CompanyID = Company.ID, DeptID = Dept.ID, CreateUserName = "admin", CreateDate = DateTime.Now }, CreateUserName = "admin", CreateDate = DateTime.Now });

            DbSet<SysUser> UserSet = context.Set<SysUser>();
            Users.ForEach(m => UserSet.Add(m));
            context.SaveChanges();
        }

        public void UserBaseConfigInit(EFDbContext context)
        {
            var UserBaseConfig = new SysUserBaseConfig { UserID = User.ID, DefaultThemeName = "default", CreateUserName = "admin", CreateDate = DateTime.Now };
            context.Set<SysUserBaseConfig>().AddOrUpdate(a => a.UserID, UserBaseConfig);
            context.SaveChanges();
        }
    }

    /// <summary>
    /// 数据库初始化操作类
    /// </summary>
    public class DatabaseInitializer : IDatabaseInitializer
    {
        /// <summary>
        /// 数据库初始化
        /// </summary>
        public void Initialize(bool migrate = true)
        {
            if (!migrate)
            {
                Database.SetInitializer(new CreateConfiguration());
                using (var db = new EFDbContext())
                {
                    db.Database.Initialize(false);
                }
            }
            else
            {
                Database.SetInitializer(new MigrateDatabaseToLatestVersion<EFDbContext, MigrateConfiguration>());
            }
        }
    }
}
